from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
import json
# Create your views here.
# FBV
from django.urls import reverse
from django.views import View

from django.views.decorators.csrf import csrf_exempt, csrf_protect  # 免除csrf验证
from django.utils.decorators import method_decorator
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning, URLPathVersioning

from App.models import UserInfo, UserToken, Role, RoleSerializer, UserGroup


class VisitThrottle(object):
    def allow_request(self, request, *args, **kwargs):
        # 获取IP
        remote_ip = request._request.META.get('REMOTE_ADDR')
        return False  # 访问频率过高 被限制
        return True  # 可以访问

    def wait(self):
        pass


class MyBaseView(object):
    def dispatch(self, request, *args, **kwargs):
        print()
        result = super(MyBaseView, self).dispatch(request, *args, **kwargs)
        print()
        return result


class ParamVersion(object):
    def determine_version(self, request, *args, **kwargs):
        version = request.query_params.get('version')  # 获取版本号
        return version


@csrf_exempt
def users(request):
    alist = []
    return HttpResponse(json.dumps(alist))


# path('', views.StudentViews.as_view()),
# CBV
# 基于反射实现根据请求方式不同，执行不同的方法

class StudentViews(View):
    # @csrf_exempt # 无效
    @method_decorator(csrf_exempt)  # 并加到dispatch
    def get(self, request, *args, **kwargs):
        return HttpResponse('GET')


class DogView(View):
    pass


from rest_framework import exceptions


class MyAuthentication(object):
    def authenticate(self, request):
        token = request._request.GET.get('token')
        if token and (token in tokens):
            # return ('ok', None)
            return (tokens['token'], None)
        else:
            raise exceptions.AuthenticationFailed('用户认证失败哦')

    def authenticate_header(self, v):
        pass


class MyPermission(object):
    message = '必须是svi'

    def has_permission(self, request, view):
        if request.user.user_type == 1:
            return False
        return True


class MyPermission2(object):
    def has_permission(self, request, view):
        if request.user.user_type == 3:
            return False
        return True


# from django.views import View
from rest_framework.views import APIView


class DogApiView(APIView):
    authentication_classes = [MyAuthentication, ]

    def get(self, request, *args, **kwargs):
        return HttpResponse('GET')


def md5(user):
    import hashlib
    import time
    ctime = str(time.time())
    m = hashlib.md5(bytes(user, encoding='utf-8'))
    m.update(bytes(ctime, encoding='utf-8'))
    return m.hexdigest()


tokens = {

}


# 用户登录
class AuthView(APIView):
    def post(self, request, *args, **kwargs):
        res = {'code': 1000, 'msg': None}
        try:
            user = request._request.POST.get('username')
            pwd = request._request.POST.get('password')
            # obj = User.objects.filter().first()
            if user == 'test' and pwd == '123456':
                token = md5(user)
                tokens[token] = UserInfo(username=user, password=pwd)
                res['token'] = token
                # UserToken.objects.update_or_create(user=user, defaults={'token': token})
            else:
                res = {'code': 500, 'msg': '登录失败'}
        except Exception as e:
            res = {'code': 500, 'msg': '异常'}
            print(e)
        return JsonResponse(res)


class OrderView(APIView):
    # 添加自定义认证
    authentication_classes = [MyAuthentication, ]

    def get(self, request, *args, **kwargs):
        orders = [
            {'name': 'good1', 'count': 1}
        ]
        res = {'code': 1000, 'msg': None}
        res['data'] = orders
        print('request.user', request.user)
        print('request.auth', request.auth)

        return JsonResponse(res)

    def post(self, request, *args, **kwargs):
        pass


class UserInfoView(APIView):
    permission_classes = [MyPermission, ]

    # throttle_classes = [VisitThrottle] # ip限制

    def get(self, request, *args, **kwargs):
        res = {'code': 1000, 'msg': None}

        return JsonResponse(res)

    def post(self, request, *args, **kwargs):
        pass


from rest_framework import serializers


# 自定义显示字段类
class MyFiled(serializers.CharField):
    def to_representation(self, value):
        print(value)
        return 'xxxx'


class UserInfoSerializer(serializers.ModelSerializer):
    # x1 = MyFiled(source='username') # 自定义字段
    # 使用ip地址
    group_id = serializers.HyperlinkedIdentityField(view_name='gp', lookup_field='group_id', lookup_url_kwarg='pk')

    utype = serializers.CharField(source='user_type')

    class Meta:
        model = UserInfo
        fields = '__all__'  # 序列化所有的字段
        # fields = ['id','username', 'utype', 'group']
        # extra_kwargs = { 'group': {'source': 'group.'}}
        depth = 1  # 数据的深度 0～10官方


# extra_kwargs = {
#     "url"" : {
#     "view_name": "指定查单条记录的  view_name即可",
#     "lookup_field": "默认是 pk,可以自己定义需要的占位符"
# 'lookup_url_kwarg': '', 新字段
# }
# }

class UserInfoSerializer2(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()
    utype = serializers.CharField(source='user_type')
    dtype = serializers.CharField(source='get_user_type_display')
    gp = serializers.CharField(source='group.title')
    roles = serializers.CharField(source='roles.all')

    rls = serializers.SerializerMethodField()

    def get_rls(self, row):
        return []  # 自定义返回


class UsersView(APIView):
    # versioning_class = ParamVersion # 自定义版本号
    # versioning_class = QueryParameterVersioning # 使用已有的
    # versioning_class = URLPathVersioning

    # parser_classes = [JSONParser]
    def get2(self, request, *args, **kwargs):
        print(request.version)  # 从版本类中获取

        # 反向生成URL (基于 rest framework)
        url = request.versioning_scheme.reverse(viewname='uuu', request=request)
        # 反向生成url (django)
        url = reverse(viewname='uuu', kwargs={'version': 2})
        print(request.data)

    def get(self, request, *args, **kwargs):
        result = {'code': 1000, 'msg': None}
        # role = Role(title='护士')
        # role.save()
        # group = UserGroup(title='二组')
        # group.save()
        # user = UserInfo(username='test2',password=123, user_type=1, group=group)
        # user.save()
        # user.roles.add(role)
        # user = UserInfo(username='李易峰2',password=123, user_type=1, group=group)
        # user.save()
        # user.roles.add(role)

        users = UserInfo.objects.all()
        ser = UserInfoSerializer(instance=users, many=True, context={'request': request})
        result = json.dumps(ser.data, ensure_ascii=False)
        return HttpResponse(result)


class RolesView(APIView):
    def get(self, request, *args, **kwargs):
        # role = Role(title='管理员')
        # role.save()
        roles = Role.objects.all()  # Object of type QuerySet is not JSON serializable
        res = {'code': 1000, 'msg': None}
        ser = RoleSerializer(instance=roles, many=True)
        # ser = RoleSerializer(instance=roles.first(), many=False) # 单个数据
        res['data'] = ser.data
        # res['data'] = json.dumps(list(roles), ensure_ascii=False) # Object of type Role is not JSON serializable
        return JsonResponse(res)


class TitleValidator(object):
    def __init__(self, base):
        self.base = base

    def __call__(self, value):
        if not value.startswith(self.base):
            raise serializers.ValidationError('标题必须%s开头' % self.base)


class GroupSerializer(serializers.ModelSerializer):
    title = serializers.CharField(error_messages={'required': 'title is not null'},
                                  validators=[TitleValidator('abc'), ])

    class Meta:
        model = UserGroup
        fields = '__all__'  # 序列化所有的字段


class GroupView(APIView):
    parser_classes = [JSONParser]

    def get(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        group = UserGroup.objects.filter(pk=pk).first()
        print(group)
        ser = GroupSerializer(instance=group, many=False)
        return HttpResponse(json.dumps(ser.data, ensure_ascii=False))

    def post(self, request, *args, **kwargs):

        print(request.data)
        # 验证data 是否合法
        ser = GroupSerializer(data=request.data)
        if ser.is_valid():
            print('ok')
        else:
            print(ser.errors)  # {'title': [ErrorDetail(string='该字段是必填项。', code='required')]}
        return HttpResponse('post')


from rest_framework import pagination
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer


# 分页
class PagerView(APIView):
    def get(self, request, *args, **kwargs):
        roles = Role.objects.all()
        print(roles)
        pg = pagination.PageNumberPagination()  # 可以自定义PageNumberPagination并修改参数
        page_data = pg.paginate_queryset(queryset=roles, request=request, view=self)
        print(page_data)
        ser = RoleSerializer(instance=page_data, many=True)
        # return pg.get_paginated_response(ser.data)
        return Response(ser.data)


from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin, CreateModelMixin


class AView(GenericAPIView):
    queryset = Role.objects.all()  # 准备数据
    # serializer_class =
    # pagination_class =
    pass


class ViewSetView(GenericViewSet):
    # renderer_classes =[]
    queryset = Role.objects.all()  # 准备数据
    serializer_class = RoleSerializer

    def list(self, request, *args, **kwargs):
        return Response('list')

    def create(self, request, *args, **kwargs):
        return Response('create ')
